package com.vhuan.self_discipline_service.serviceimpl.battery;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vhuan.common.constant.common.DeleteFlag;
import com.vhuan.common.constant.common.OverFlag;
import com.vhuan.self_discipline_service.domain.battery.dto.BatteryBehaviorDTO;
import com.vhuan.self_discipline_service.domain.battery.dto.BatteryDTO;
import com.vhuan.self_discipline_service.domain.battery.po.BatteryBehaviorEntity;
import com.vhuan.self_discipline_service.domain.battery.po.BatteryEntity;
import com.vhuan.self_discipline_service.domain.battery.po.BatteryPeriodEntity;
import com.vhuan.self_discipline_service.mapper.battery.BatteryBehaviorMapper;
import com.vhuan.self_discipline_service.mapper.battery.BatteryMapper;
import com.vhuan.self_discipline_service.mapper.battery.BatteryPeriodMapper;
import com.vhuan.self_discipline_service.service.battery.BatteryService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class BatteryServiceImpl extends ServiceImpl<BatteryMapper, BatteryEntity> implements BatteryService {
    private final BatteryMapper batteryMapper;
    private final BatteryPeriodMapper batteryPeriodMapper;
    private final BatteryBehaviorMapper batteryBehaviorMapper;
    private static final Logger logger = LoggerFactory.getLogger(BatteryServiceImpl.class);

    /**
     * 获取电池列表
     * @param uid 用户id
     * @return 电池列表
     */
    @Override
    public List<BatteryDTO> getBatteryList(Long uid) {
        return batteryMapper.getBatteryList(uid);
    }

    /**
     * 新增电池
     * @param batteryDTO 电池信息
     */
    @Override
    @Transactional
    public void addBattery(BatteryDTO batteryDTO) {
        try {
            //1.新增电池表
            BatteryEntity battery= BeanUtil.copyProperties(batteryDTO,BatteryEntity.class);
            batteryMapper.insert(battery);
            //2.新增电池周期表
            BatteryPeriodEntity batteryPeriod=new BatteryPeriodEntity(battery);
            batteryPeriodMapper.insert(batteryPeriod);
        }catch (Exception e){
            logger.error("Error adding battery and battery period: {}", batteryDTO, e);
            throw new RuntimeException("Failed to add battery and battery period", e);
        }

    }

    /**
     * 删除电池
     * @param batteryId 电池id
     */
    @Override
    public void deleteBattery(Long batteryId) {
        BatteryEntity battery=new BatteryEntity();
        battery.setId(batteryId);
        battery.setDeleteFlag(DeleteFlag.DELETE);
        baseMapper.updateById(battery);
    }

    /**
     * 新增电池行为
     * @param batteryBehaviorDTO 电池行为信息
     */
    @Override
    @Transactional
    public void addBatteryBehavior(BatteryBehaviorDTO batteryBehaviorDTO) {
        try {
            if (batteryBehaviorDTO == null) {
                throw new IllegalArgumentException("BatteryBehaviorDTO cannot be null");
            }

            //1.新增电池行为表
            BatteryBehaviorEntity batteryBehavior=BeanUtil.copyProperties(batteryBehaviorDTO,BatteryBehaviorEntity.class);
            batteryBehaviorMapper.insert(batteryBehavior);

            //2.更新电池周期表,battery_period的capacity字段加上本次行为积分
            LambdaQueryWrapper<BatteryPeriodEntity> wrapper=new LambdaQueryWrapper<BatteryPeriodEntity>().
                    eq(BatteryPeriodEntity::getId,batteryBehaviorDTO.getBatteryPeriodId());
            batteryPeriodMapper.updateCapacityByIds(wrapper,batteryBehaviorDTO.getBehaviorPoint());
        }catch (Exception e){
            logger.error("Error adding battery behavior: {}", batteryBehaviorDTO, e);
            throw new RuntimeException("Failed to add battery behavior", e);
        }

    }

    /**
     * 删除电池行为
     * @param batteryBehaviorId 电池行为id
     */
    @Override
    @Transactional
    public void deleteBatteryBehavior(Long batteryBehaviorId) {
        try {
            //1.查询是否已被删除
            BatteryBehaviorEntity batteryBehavior=batteryBehaviorMapper.selectOne(new LambdaQueryWrapper<BatteryBehaviorEntity>().eq(BatteryBehaviorEntity::getId,batteryBehaviorId).eq(BatteryBehaviorEntity::getDeleteFlag,DeleteFlag.NOT_DELETE));
            if (batteryBehavior==null){
                throw new IllegalArgumentException("BatteryBehaviorEntity cannot be null");
            }
            //2.更新为删除状态
            batteryBehavior.setDeleteFlag(DeleteFlag.DELETE);
            batteryBehaviorMapper.updateById(batteryBehavior);
            //3.更新电池周期表,battery_period的capacity字段减去本次行为积分
            batteryPeriodMapper.updateCapacityByIds(new LambdaQueryWrapper<BatteryPeriodEntity>().eq(BatteryPeriodEntity::getId,batteryBehavior.getBatteryPeriodId()),-batteryBehavior.getBehaviorPoint());
        }catch (Exception e){
            logger.error("Error deleting battery behavior: {}", batteryBehaviorId, e);
            throw new RuntimeException("Failed to delete battery behavior", e);
        }
    }

    /**
     * 每天23:59:59检查生成下一轮电池周期
     */
    @Override
    @Scheduled(cron = "0 59 23 * * ? ")
    public void generarteBatteryPeriodEveryDay() {
        //1.查询所有未删除的电池且今天为当前周期最后一天的电池周期
        List<BatteryPeriodEntity> batteryPeriodList=batteryPeriodMapper.selectList(new LambdaQueryWrapper<BatteryPeriodEntity>().
                eq(BatteryPeriodEntity::getDeleteFlag,DeleteFlag.NOT_DELETE).
                eq(BatteryPeriodEntity::getEndTime, LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999)));

        //2.生成下一轮电池周期
        batteryPeriodList.forEach(batteryPeriod -> {
            //2.1设置已完结状态
            batteryPeriod.setOverFlag(OverFlag.OVER);
            batteryPeriod.setGradeByCapacity();
            batteryPeriodMapper.updateById(batteryPeriod);

            //2.2生成下一轮电池周期
            BatteryPeriodEntity batteryPeriodEntity=new BatteryPeriodEntity(batteryPeriod);
            batteryPeriodMapper.insert(batteryPeriodEntity);
        });
    }
}
